package com.lyn.qrcode;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextUtils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.yanzhenjie.zbar.Image;
import com.yanzhenjie.zbar.ImageScanner;
import com.yanzhenjie.zbar.Symbol;
import com.yanzhenjie.zbar.SymbolSet;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

public class QrCodeManager {

    private static class QrCodeManagerTypeClass {
        private static QrCodeManager instance = new QrCodeManager();
    }

    public static QrCodeManager getInstance() {
        return QrCodeManagerTypeClass.instance;
    }

    /**
     * 1.设置二维码相关配置
     */
    private final Hashtable<DecodeHintType, String> decodeHintHashtable;
    private final Hashtable<EncodeHintType, String> encodeHintHashtable;
    private final Reader reader;
    private final QRCodeWriter qrCodeWriter;
    private final ImageScanner imageScanner;
    private final Image image;

    public QrCodeManager() {
        decodeHintHashtable = new Hashtable<>();
        //字符集
        decodeHintHashtable.put(DecodeHintType.CHARACTER_SET, "UTF-8");
        encodeHintHashtable = new Hashtable<>();
        //字符集
        encodeHintHashtable.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        // 容错率设置
        encodeHintHashtable.put(EncodeHintType.ERROR_CORRECTION, "L");
        // 空白边距设置
        encodeHintHashtable.put(EncodeHintType.MARGIN, "2");

        reader = new MultiFormatReader();
        qrCodeWriter = new QRCodeWriter();
        imageScanner = new ImageScanner();
        image = new Image(640, 480, "Y800");
    }

    private int width = 300;
    private int height = 300;

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public Bitmap create(String qrCode) {
        if (TextUtils.isEmpty(qrCode)) {
            return null;
        }
        BitMatrix bitMatrix = null;
        try {
            bitMatrix = qrCodeWriter.encode(qrCode, BarcodeFormat.QR_CODE, width, height, encodeHintHashtable);
        } catch (WriterException e) {
            e.printStackTrace();
            return null;
        }
        int[] pixels = new int[width * height];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                //bitMatrix.get(x,y)方法返回true是黑色色块，false是白色色块
                if (bitMatrix.get(x, y)) {
                    pixels[y * width + x] = Color.BLACK;
                } else {
                    pixels[y * width + x] = Color.WHITE;
                }
            }
        }
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return bitmap;
    }


    public Result scanBitmap(Bitmap scanBitmap) {
        int[] intArray = new int[scanBitmap.getWidth() * scanBitmap.getHeight()];
        scanBitmap.getPixels(intArray, 0, scanBitmap.getWidth(), 0, 0, scanBitmap.getWidth(), scanBitmap.getHeight());
        RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap.getWidth(), scanBitmap.getHeight(), intArray);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        try {
            return reader.decode(bitmap1, decodeHintHashtable);
        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (ChecksumException e) {
            e.printStackTrace();
        } catch (FormatException e) {
            e.printStackTrace();
        }
        return null;
    }


    private final List<QrCode> qrCodeList = new ArrayList<>();

    public List<QrCode> scanNv21(byte[] data, int width, int height) {
        image.setSize(width, height);
        image.setData(data);
        qrCodeList.clear();
        int result = imageScanner.scanImage(image);
        if (result == 0) {
            return qrCodeList;
        }
        SymbolSet symSet = imageScanner.getResults();
        for (Symbol sym : symSet) {
            if (sym == null) {
                continue;
            }
            int[] coordinate = sym.getBounds();
            Rect rect = new Rect();
            rect.left = coordinate[0];
            rect.top = coordinate[1];
            rect.right = (coordinate[0] + coordinate[2]);
            rect.bottom = (coordinate[1] + coordinate[3]);

            QrCode qrCode = new QrCode();
            qrCode.setQrCode(sym.getData());
            qrCode.setNv21Data(data);
            qrCode.setRect(rect);
            qrCodeList.add(qrCode);
        }
        return qrCodeList;
    }


}
